home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
vballs11.zip
/
BALLS1.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-06
|
4KB
|
235 lines
/*
* balls1.c - Draw 3-D balls in 320x200x256 (VGA) mode
*
* Uses BGI interface
*
* Adapted by: Scott J. Walter (GEnie: S.Walter4)
*
*/
/* INCLUDES */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <graphics.h>
/* DEFINES */
#define TRUE 1
#define FALSE 0
/* TYPEDEFS */
typedef unsigned char UBYTE;
typedef struct {
UBYTE Rvalue;
UBYTE Gvalue;
UBYTE Bvalue;
} ColorValue;
/* GLOBALS */
double light[3] = { -2.0, -2.0, 3.0 }; /* light source upr lft */
int radius = 40;
ColorValue P[256];
/* FUNCTIONS */
/*
* Normalize a vector to unit magnitude. Calculate the magnitude as:
*
* magnitude = sqrt ( x^2 + y^2 + z^2 )
*
* Normalize the vector by dividing each coordinate by the magnitude.
*/
void normalize(double this_vec[])
{
double mag;
int count;
mag = 0.0;
for(count = 0; count < 3; count++)
mag = mag + (this_vec[count] * this_vec[count]);
mag = sqrt(mag);
for(count = 0; count < 3; count++)
this_vec [count] = this_vec [count]/mag;
}
/* Calculate the cosine of the angle between two vectors.
*
* dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
*/
double dot_prod(double vec1[], double vec2[])
{
double COSINE;
int count;
COSINE = 0.0;
for (count = 0; count < 3; count++)
COSINE += vec1 [count] * vec2 [count];
return (COSINE);
}
void put_atom(int R, int index, int xc, int yc, double l_source[])
{
double s_point[3];
int R2 = R*R, color = 0;
double x, y, z, r, intensity;
normalize(l_source); /* normalize the light source */
for(x=-R;x<=+R;x++) /* scan an area 2R x 2R */
{
for(y=-R;y<=+R;y++)
{
r = (x*x) + (y*y); /* check that the pixel is within a */
if(r <= R2) /* circle of radius R */
{
z = sqrt((R2)-r); /* calculate the altitude of the point */
s_point[0] = x; /* set the normal surface vector to the */
s_point[1] = y; /* coordinates of the point */
s_point[2] = z;
intensity = random(100);
intensity /= 100;
intensity += 64 * dot_prod(s_point,l_source)/R;
color = (int)intensity;
color = color<0 ? 0 : (color> 63 ? 63 : color);
putpixel(x+xc,y+yc,index*64 + color);
}
}
}
}
void VGASetAllPalette(void)
{
struct REGPACK r;
r.r_ax = 0x1012;
r.r_bx = 0x0000;
r.r_cx = 0x0100;
r.r_es = FP_SEG(&P[0]);
r.r_dx = FP_OFF(&P[0]);
intr(0x10, &r);
}
void Hsi2Rgb(float H, float S, float I, int palpos)
{
float T, Rv, Gv, Bv;
float Pi = 3.14159265358979;
H = H < 0.0 ? 1.0 + H : (H > 1.0 ? H - 1.0 : H);
S = S < 0.0 ? 1.0 + S : (S > 1.0 ? S - 1.0 : S);
I = I < 0.0 ? 1.0 + I : (I > 1.0 ? I - 1.0 : I);
T = 2.0 * Pi * H;
Rv = 1 + S * sin(T - 2 * Pi / 3);
Gv = 1 + S * sin(T);
Bv = 1 + S * sin(T + 2 * Pi / 3);
T = 63.999 * I / 2;
P[palpos].Rvalue = (UBYTE)(Rv * T);
P[palpos].Gvalue = (UBYTE)(Gv * T);
P[palpos].Bvalue = (UBYTE)(Bv * T);
}
int huge DetectVGA256(void)
{
int gdriver, gmode;
detectgraph(&gdriver, &gmode);
if((gdriver==VGA)||(gdriver==MCGA))
return 0; /* Default video mode = 0 */
else
return grError; /* Couldn't detect hardware */
}
/* MAIN */
void main(void)
{
int Y, Z, ErrorCode, Driver = DETECT, Mode;
installuserdriver("VGA256", DetectVGA256);
initgraph(&Driver, &Mode, "");
ErrorCode = graphresult();
if(ErrorCode!=grOk)
{
printf("Error: %s\n", grapherrormsg(ErrorCode));
exit(1);
}
randomize();
for(Y=0;Y<4;Y++)
for(Z=0;Z<64;Z++)
Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, Y*64+Z);
VGASetAllPalette();
for(Y=0;Y<2;Y++)
for(Z=0;Z<2;Z++)
put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
putch(7);
getch();
closegraph();
}